#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <stdint.h>
#include <wchar.h>
#include <dirent.h>
#include <signal.h>
#include <vector>
#include <arpa/inet.h>
#include "tests.hpp"
#include "utils.hpp"

#define UNIT_TEST_CATCH raise(SIGTRAP); result += 1;
// #define UNIT_TEST_CATCH result += 1;

static int TestUtils()
{
	int result = 0;
	
	{
		const char *filePathnameTests[] = {
			"", ""
			, "/test_data/", "test_data/"
			, "./test_data/inner_folder/", "inner_folder/"
			, ".\\test_data\\inner_folder\\", "inner_folder\\"
			, "./test_data/", "test_data/"
			, ".\\test_data\\", "test_data\\"
			, "./", "./"
			, ".\\", ".\\"
			, "./test_data/AAA.csv", "AAA.csv"
			, ".\\test_data\\AAA.csv", "AAA.csv"
			, "./AAA.csv", "AAA.csv"
			, ".\\AAA.csv", "AAA.csv"
		};
		
		for (uint8_t i = 0; i < sizeof(filePathnameTests)/sizeof(filePathnameTests[0]); i+=2) {
			const char *resultItem = LastPathItem(filePathnameTests[i]);
			if (strcmp(filePathnameTests[i+1], resultItem) != 0) {
				UNIT_TEST_CATCH
			}
		}
	}
	
	{
		const char *filePathnameTests[] = {
			"", (char*)0, ""
			, "/BBB/", (char*)2, "BBB/"
			, "/BBB/", (char*)1, "/BBB/"
			, "./AAA/BBB/", (char*)7, "BBB/"
			, "./AAA/BBB/", (char*)6, "AAA/BBB/"
			, "AAA/BBB/", (char*)0, "AAA/BBB/"
			, "AAA/BBB/", (char*)EOF, "BBB/"
		};
		
		for (uint8_t i = 0; i < sizeof(filePathnameTests)/sizeof(filePathnameTests[0]); i+=3) {
			const char *resultItem = LastPathItem(filePathnameTests[i], (size_t)filePathnameTests[i+1]);
			if (strcmp(filePathnameTests[i+2], resultItem) != 0) {
				UNIT_TEST_CATCH
			}
		}
	}
	
	{
		const char *filePathnameTests[] = {
			"", ""
			, "./", ""
			, ".\\", ""
			, "./test_data/inner_folder/", ""
			, ".\\test_data\\inner_folder\\", ""
			, "./test_data/", ""
			, ".\\test_data\\", ""
			, "./test_data/AAA.csv", "AAA.csv"
			, ".\\test_data\\AAA.csv", "AAA.csv"
			, "./AAA.csv", "AAA.csv"
			, ".\\AAA.csv", "AAA.csv"
			, "AAA.csv", "AAA.csv"
		};
		
		for (uint8_t i = 0; i < sizeof(filePathnameTests)/sizeof(filePathnameTests[0]); i+=2) {
			const char *resultItem = FilenameFromPathname(filePathnameTests[i]);
			if (strcmp(filePathnameTests[i+1], resultItem) != 0) {
				UNIT_TEST_CATCH
			}
		}
	}
	
	{
		const char *filePathnameTests[] = {
			"", "", (char*)0
			, "AAA", "", (char*)0
			, "\\AAA.csv", "/AAA.csv", (char*)0
			, "AAA", "AAA", (char*)3
			, "AAB", "AAA", (char*)2
			, "AA", "AAA", (char*)2
			, "ABB", "AAA", (char*)1
			, "ABB", "A", (char*)1
		};
		
		for (uint8_t i = 0; i < sizeof(filePathnameTests)/sizeof(filePathnameTests[0]); i+=3) {
			size_t resultItem = StrSameChrFor(filePathnameTests[i], filePathnameTests[i+1]);
			if ((size_t)filePathnameTests[i+2] != resultItem) {
				UNIT_TEST_CATCH
			}
		}
	}
	
	{
		const char *filePathnameTests[] = {
			"", "", (char*)0
			, "AAA", "", (char*)0
			, "\\AAA.csv", "/AAA.csv", (char*)0
			, "./folder/folder1/AAA.csv", "./folder/folder2/AAA.csv", (char*)9
			, "AAA", "AAA", (char*)3
			, "AAB", "AAA", (char*)0
			, "AA", "AAA", (char*)0
			, "/ABB", "/AAA", (char*)1
			, "\\ABB", "\\AAA", (char*)1
			, "./ABB", "./AAA", (char*)2
			, ".\\ABB", ".\\AAA", (char*)2
			, "/ABB", "/A", (char*)1
		};
		
		for (uint8_t i = 0; i < sizeof(filePathnameTests)/sizeof(filePathnameTests[0]); i+=3) {
			size_t resultItem = StrSamePathFor(filePathnameTests[i], filePathnameTests[i+1]);
			if ((size_t)filePathnameTests[i+2] != resultItem) {
				UNIT_TEST_CATCH
			}
		}
	}
	
	{
		const char *filePathnameTests[] = {
			"", (char*)0
			, "A", (char*)1
			, "AAA", (char*)3
			, "AAA/", (char*)4
			, "AAA\\", (char*)4
			, "AAA/B", (char*)4
			, "AAA\\B", (char*)4
			, "AAA/BBB", (char*)4
			, "AAA\\BBB", (char*)4
			, "/", (char*)1
			, "\\", (char*)1
			, "/BBB", (char*)1
			, "\\BBB", (char*)1
			, "./BBB", (char*)2
			, ".\\BBB", (char*)2
			, "../BBB", (char*)3
			, "..\\BBB", (char*)3
		};
		
		for (uint8_t i = 0; i < sizeof(filePathnameTests)/sizeof(filePathnameTests[0]); i+=2) {
			size_t resultLen = LenOfFirstPathItem(filePathnameTests[i]);
			if ((size_t)filePathnameTests[i+1] != resultLen) {
				UNIT_TEST_CATCH
			}
		}
	}
	
	{
		const char *filePathnameTests[] = {
			"AAA/BBB/", (char*)0, (char*)0
			, "AAA/BBB/", (char*)8, "BBB/"
			, "AAA/BBB/", (char*)5, "B"
			, "AAA/BBB/", (char*)4, "AAA/"
			, "./AAA/BBB/", (char*)6, "AAA/"
			, "AAA/BBB/", (char*)EOF, "BBB/"
			, "AAA/BBB.csv", (char*)EOF, "BBB.csv"
		};
		
		for (uint8_t i = 0; i < sizeof(filePathnameTests)/sizeof(filePathnameTests[0]); i+=3) {
			const char *endPosition = filePathnameTests[i+1] == (const char*)EOF ? 0 : &filePathnameTests[i][(size_t)filePathnameTests[i+1]];
			const char *resultItem = GetItemBeforeLastPos(filePathnameTests[i], endPosition);
			if (((filePathnameTests[i+2] == 0) != (resultItem == 0))
				|| (resultItem != 0 && strcmp(filePathnameTests[i+2], resultItem) != 0)) {
				UNIT_TEST_CATCH
			}
			if (resultItem) {
				delete[] resultItem;
			}
		}
	}
	
	return result;
}

static int TestXllnHub()
{
	int result = 0;
	
	
	return result;
}

int main(int argc, char **argv)
{
	int result = 0;
	
	if (result = TestUtils()) {
		return result;
	}
	
	if (result = TestXllnHub()) {
		return result;
	}
	
	return result;
}
